package com.bosssoft.filter;

import com.bosssoft.util.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;

/**
 * @author 项昊天
 * @create 2021/8/21 9:54
 */
@Slf4j
@Component
public class JwtTokenFilter implements GlobalFilter, Ordered {

  @Value(value = "${no.need.token.access.urls:" +
                 "/user/login," +
                 "/user/register" +
                 "}")
  private HashSet<String> noNeedTokenUrls;


  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

    log.info("进入TokenFilter");

    ServerHttpRequest request = exchange.getRequest();
    String token = request.getHeaders().getFirst("token");
    log.info("token:{}", token);

    ServerHttpResponse response = exchange.getResponse();
    // 指定响应编码格式
    response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
    //拿到token里面对应的可以访问的urls
    List<String> accessUrls = JwtTokenUtil.getAccessUrlsFromToken(token);

    //拿到当前访问的uri
    String requestUri = request.getURI().getPath();
    log.info("requestUri:{}", requestUri);
    log.info("noNeedTokenUrls:{}", noNeedTokenUrls);

    //如果是不需要token就能访问的，或者是拥有该权限访问的就放行
    if (noNeedTokenUrls.contains(requestUri) || accessUrls.contains(requestUri)) {

      log.info("TokenFilter已放行");
      return chain.filter(exchange);
    }

    log.info("TokenFilter已放行");
    log.info("tokenFilter已拦截该请求:{}", requestUri + " 权限不足");
    exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
    JSONObject message = new JSONObject();
    message.put("code", 307);
    message.put("message", "权限不足");
    byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
    DataBuffer buffer = response.bufferFactory().wrap(bits);
    response.setStatusCode(HttpStatus.UNAUTHORIZED);
    return response.writeWith(Mono.just(buffer));
  }

  @Override
  public int getOrder() {
    return 0;
  }
}
